package org.softmed.rest.editor.comps;

import java.awt.Color;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseListener;

import javax.swing.JButton;
import javax.swing.JCheckBox;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JPanel;

import net.miginfocom.swing.MigLayout;

import org.restlet.Client;
import org.restlet.data.MediaType;
import org.restlet.data.Protocol;
import org.restlet.data.Response;
import org.restlet.resource.StringRepresentation;
import org.softmed.rest.editor.EditorUtil;
import org.softmed.rest.editor.FilePathAware;
import org.softmed.rest.editor.FilePathProvider;
import org.softmed.rest.editor.commons.SwingUtil;
import org.softmed.rest.editor.commons.URIProvider;
import org.softmed.rest.editor.config.Handler;
import org.softmed.rest.editor.xml.XStreamConfigurator;
import org.softmed.swing.IconManager;

import com.thoughtworks.xstream.XStream;

public abstract class HandlerEditor extends SimpleEditor implements
		ActionListener, FilePathAware {
	protected Handler handler;

	protected CustomTextField path = new CustomTextField();
	protected JCheckBox active = new JCheckBox();
	protected JLabel id = new JLabel("id");

	protected JButton getFilePaths = new JButton(IconManager.updateToServer);

	protected FilePathProvider filePathProvider;

	public HandlerEditor(URIProvider uriProvider) {
		super(uriProvider);
		uri = "handlers";

		XStreamConfigurator.configureStreamerHandler(streamer);

		active.addActionListener(this);
		path.addActionListener(this);
		getFilePaths.addActionListener(this);

		getFilePaths
				.setToolTipText("Get file path in a FQCN format from file browser at the left");

		// setup();
	}

	// public HandlerEditor(URIProvider uriProvider) {
	// super(uriProvider);
	// uri = "handlers";
	// XStreamConfigurator.configureStreamerHandler(streamer);
	// this.uriProvider = uriProvider;
	// SwingUtil.setSize(this, EditorUtil.smallestWidth,
	// EditorUtil.smallestHeight);
	// MigLayout layout = new MigLayout("left, insets " +
	// EditorUtil.smallestInsets);
	// setLayout(layout);
	//
	// add(id, "w 25!");
	// add(active, "w 20!");
	// add(path, "w 300!");
	//
	// active.addActionListener(this);
	// path.addActionListener(this);
	//
	// }

	public void createNew() throws Throwable {

		String xml = streamer.toXML(new Handler());
		Response response = client.post(getClassURI(),
				new StringRepresentation(xml, MediaType.APPLICATION_XML));
		if (response.getStatus().getCode() != 201)
			throw new RuntimeException("Error creating handler with xml;" + xml);
		xml = response.getEntity().getText();
		handler = (Handler) streamer.fromXML(xml);
		setEntity(handler);

	}

	public void setEntity(Object h) throws Throwable {
		handler = (Handler) h;
		active.setSelected(handler.isActive());
		path.setText(handler.getPath());
		id.setText(handler.getId().toString());
		repaint();
	}

	public void loadEntity(String uri) throws Throwable {
		Response response = client.get(uri);
		if (response.getStatus().getCode() != 200)
			throw new RuntimeException("Error fetching entity " + uri);
		String xml = response.getEntity().getText();
		handler = (Handler) streamer.fromXML(xml);
		setEntity(handler);
	}

	public void refresh() throws Throwable {
		loadEntity(handler.getUri());
	}

	@Override
	public void actionPerformed(ActionEvent e) {
		super.actionPerformed(e);
		if (!editable)
			return;
		try {
			Object source = e.getSource();

			if (source == getFilePaths) {
				String filePath = filePathProvider
						.getSelectedFileRelativePath();
				if (filePath == null)
					throw new RuntimeException("No file selected!");

				int index = filePath.lastIndexOf(".");
				int dirIndex = filePath.lastIndexOf("/");

				if (index > 0 && index > dirIndex)
					filePath = filePath.substring(0, index);

				// if (filePath.startsWith("/"))
				// filePath = filePath.substring(1);

				filePath = filePath.replace('/', '.');

				handler.setPath(filePath);

				path.setText(filePath);

				path.startDelayedSaving();

				// EditorUtil
				// .saveTextField(client, getInstanceURI(), path, "path");
				return;

			}

			if (source == active) {
				active.setForeground(Color.RED);
				Response response = client.put(getInstanceURI() + "/"
						+ "active", new StringRepresentation(active
						.isSelected()
						+ ""));
				if (response.getStatus().getCode() != 200)
					throw new RuntimeException(
							"Error changing app active state to "
									+ active.isSelected());
				active.setForeground(Color.BLACK);
			} else if (source == path) {
				EditorUtil
						.saveTextField(client, getInstanceURI(), path, "path");
			}
		} catch (Throwable t) {
			t.printStackTrace();
			JOptionPane.showMessageDialog(this, t.getMessage(), "Error",
					JOptionPane.ERROR_MESSAGE);
		}
	}

	private String getInstanceURI() {
		return getClassURI() + "/" + handler.getId();
	}

	public void addMouseListener(MouseListener list) {
		super.addMouseListener(list);
		active.addMouseListener(list);
		path.addMouseListener(list);
	}

	public void removeMouseListener(MouseListener list) {
		super.removeMouseListener(list);
		active.removeMouseListener(list);
		path.removeMouseListener(list);
	}

	public void setEditable(boolean editable) {
		this.editable = editable;
		active.setEnabled(editable);
		path.setEditable(editable);
	}

	@Override
	public Object getEntity() {
		return handler;
	}

	@Override
	public void setFilePathProvider(FilePathProvider provider) {
		this.filePathProvider = provider;

	}
}
